﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.ServiceModel;
using System.Text;
using AcceptServer;
using BLL;
using Common;
using Model;

namespace PositionServer.Service
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple, IncludeExceptionDetailInFaults = true)]
    class PositionService : IPositionService
    {
        public int TestWCF()
        {
            return 1;
        }
         
        readonly BUser _bUser = new BUser();
        readonly BTaxiGpsHistory _bTaxiGpsHistory = new BTaxiGpsHistory();
        readonly BRole _bRole = new BRole();               
        readonly BGmapoverlay _bGmapoverlay = new BGmapoverlay();
        private readonly BPhoneUser _bPhoneUser = new BPhoneUser();          
        private readonly BCompany _bCompany = new BCompany();
        private readonly BDriver _bDriver = new BDriver();
        private readonly BOrder _bOrder = new BOrder();
        private readonly BTaxi _bTaxi = new BTaxi();

        public string GetClientVersion()
        {
            return OperateConfig.GetClientVersion();
        }

        public OrderInfo GetAnOrder(int userId)
        {
            UserInfo user = _bUser.GetModel(userId);
            if (user==null)
            {
                return null;
            }
            lock (AcceptMainForm.OrderList.SyncRoot)
            {
                foreach (OrderInfo orderInfo in AcceptMainForm.OrderList.Values)
                {
                   
                    if (orderInfo.State==OrderState.S1_NewOrder)
                    {
                        orderInfo.State = OrderState.S2_TakenByPlatform;
                        orderInfo.UserId = userId;
                        orderInfo.UserRealName = user.RealName;
                        orderInfo.TakeTime = DateTime.Now;
                        _bOrder.UpdateWhenGetByPlatform(orderInfo.Id,userId);

                        return orderInfo;
                    }
                }
            }
            return null;
        }

        public int SubmitAnOrder(OrderInfo order)
        {
            if (!AcceptMainForm.OrderList.Contains(order.Id))
            {
                return 0;//不在服务器列表中..
            }                        
            //bool dbUpdate = _bOrder.UpdateOneColumns(order.Id, "State", "3");
            order.SubmitTime = DateTime.Now;
            bool dbUpdate = _bOrder.UpdateWhenPlatformSubmit(order);
            if (!dbUpdate)
            {
                return 1;//数据库更新失败..
            }
            order.State = OrderState.S3_SetCarAndDriver;
            AcceptMainForm.OrderList[order.Id] = order;
            try
            {
                byte[] phoneNumberbyts = CommonRoutine.BcdStringToBytes(
                 order.PhoneNumber.PadLeft(12, '0'));

                #region  发送给用户
                IPEndPoint phoneUserIp = AcceptMainForm.IpEndPointList[order.PhoneNumber] as IPEndPoint;
                if (phoneUserIp!=null)
                { 
                    List<byte> body = new List<byte>();
                    //--------orderCount 1byte
                    body.Add(1);
                    //--------orderId  4byte
                    body.AddRange(CommonRoutine.BcdStringToBytes(order.PhoneOrderId));
                    //--------carPhoneNumber 6byte
                    string carphonestr = order.CarPhoneNumber;
                    byte[] carphoneBcd = CommonRoutine.BcdStringToBytes(
                        carphonestr.PadLeft(12, '0'));
                    body.AddRange(carphoneBcd);
                    //--------driverPhoneNumber 6byte
                    string driverphonestr = order.DriverPhoneNumber;
                    byte[] driverphoneBcd = CommonRoutine.BcdStringToBytes(
                        driverphonestr.PadLeft(12, '0'));
                    body.AddRange(driverphoneBcd);
                    //--------price 2byte
                    byte[] bytePrice = BitConverter.GetBytes(order.Price);
                    Array.Reverse(bytePrice);
                    body.AddRange(bytePrice);

                    byte[] messageHead = OperateAgreement.GetMessageHead(
                        ConstParameters.CmdPhoneUserSendOrderInfo,
                        false, false, body.Count, phoneNumberbyts,
                                                        new byte[] { 0, 0 }, 0, 0);
                    byte[] tempData = OperateAgreement.PackageSendData(messageHead, body.ToArray());
                    AcceptMainForm.SendDataToIpAddress(
                     tempData, phoneUserIp, order.PhoneNumber); 
                }             
                #endregion
                 
                //已注销，改完在客户支付后发送到车载
                #region 发送给车载端
                //IPEndPoint taxiIp = null;
                //lock (AcceptMainForm.TaxiList.SyncRoot)
                //{
                //    TaxiInfo taxi = AcceptMainForm.TaxiList[order.CarPhoneNumber] as TaxiInfo;
                //    if (taxi != null && taxi.DriverCardId == order.DriverCardId)
                //    {
                //        taxiIp = AcceptMainForm.IpEndPointList[order.CarPhoneNumber] as IPEndPoint;
                //    }
                //}
                //if (taxiIp != null)
                //{
                //    List<byte> body2 = new List<byte>();
                //    string strCardId = order.DriverCardId;
                //    byte[] cardIdbytes = new byte[10];
                //    byte[] tempbytes = Encoding.GetEncoding("GBK").GetBytes(strCardId);
                //    for (int k = 0; k < tempbytes.Length; k++)
                //    {
                //        if (k < tempbytes.Length)
                //        {
                //            cardIdbytes[k] = tempbytes[k];
                //        }
                //        else
                //        {
                //            cardIdbytes[k] = 32;
                //        }
                //    }
                //    //--------cardId  10byte
                //    body2.AddRange(cardIdbytes); 
                //    //--------orderId  4byte                
                //    byte[] idBytes = BitConverter.GetBytes(order.Id);
                //    Array.Reverse(idBytes);
                //    body2.AddRange(idBytes);                   
                //    //--------driverPhoneNumber 6byte                                
                //    body2.AddRange(phoneNumberbyts);
                //    //--------startLng 5byte               
                //    string startLngstr =
                //        ((order.StartLng * Math.Pow(10, 6)).ToString().PadLeft(10, '0'));
                //    byte[] lstartLngBytes = CommonRoutine.BcdStringToBytes(startLngstr);
                //    body2.AddRange(lstartLngBytes);
                //    //--------startLat 5byte               
                //    string startLatstr =
                //        ((order.StartLng * Math.Pow(10, 6)).ToString().PadLeft(10, '0'));
                //    byte[] startLatBytes = CommonRoutine.BcdStringToBytes(startLatstr);
                //    body2.AddRange(startLatBytes);
                //    //--------endLng 5byte               
                //    string endLngstr =
                //        ((order.StartLng * Math.Pow(10, 6)).ToString().PadLeft(10, '0'));
                //    byte[] endLngBytes = CommonRoutine.BcdStringToBytes(endLngstr);
                //    body2.AddRange(endLngBytes);
                //    //--------endLat 5byte               
                //    string endLatstr =
                //        ((order.StartLng * Math.Pow(10, 6)).ToString().PadLeft(10, '0'));
                //    byte[] endLatBytes = CommonRoutine.BcdStringToBytes(endLatstr);
                //    body2.AddRange(endLatBytes);
                //    //--------agreeTime 7byte
                //    string agreeTime = order.AgreeStartTime.ToString("yyyyMMddHHmmss");
                //    byte[] agreeTimeBytes = CommonRoutine.BcdStringToBytes(agreeTime);
                //    body2.AddRange(agreeTimeBytes);

                //    byte[] messageHead2 = OperateAgreement.GetMessageHead(
                //        ConstParameters.CmdTaxiSendAnOrderInfo,
                //        false, false, body2.Count, phoneNumberbyts,
                //                                        new byte[] { 0, 0 }, 0, 0);
                //    byte[] tempData2 = OperateAgreement.PackageSendData(messageHead2, body2.ToArray());
                //    AcceptMainForm.SendDataToIpAddress(
                //    tempData2, taxiIp, order.CarPhoneNumber);
                //}
                #endregion  
            }
            catch (Exception ex)
            {
                return 2;//数据处理时异常
            }            
             
            AcceptMainForm.OrderList[order.Id] = order; 
            return 3;//成功
        }


        public List<Model.OrderInfo> GetOrderList(int userId)
        {
            lock (AcceptMainForm.OrderList.SyncRoot)
            {
                List<OrderInfo> orderInfos = new List<OrderInfo>();
                orderInfos.AddRange(AcceptMainForm.OrderList.Values.Cast<OrderInfo>().
                    Where(order => order.UserId == userId
                         ));
                return orderInfos;
            }
        }

        public List<Model.TaxiInfo> GetGpsByCompny(string companyNmae)
        { 
            lock (AcceptMainForm.TaxiList.SyncRoot)
            {
                List<TaxiInfo> fasterInfos = new List<TaxiInfo>();
                fasterInfos.AddRange(AcceptMainForm.TaxiList.Values.Cast<TaxiInfo>().
                    Where(faster => faster.CompanyName == companyNmae
                         )); 
                return fasterInfos;
            } 
        }


        public List<TaxiInfo> GetNearbyGps(double longitude, double latitude, double distance, int type)
        {
            double d = distance * 2 / 100.0f;
            double d2 = d;

            lock (AcceptMainForm.TaxiList.SyncRoot)
            {

                List<TaxiInfo> fasterInfos = new List<TaxiInfo>();

              

                fasterInfos.AddRange(AcceptMainForm.TaxiList.Values.Cast<TaxiInfo>().
                    Where(faster => Math.Abs(faster.Latitude - latitude) < d
                        && Math.Abs(faster.Longitude - longitude) < d2
                         ));
                

                return fasterInfos;
            }
            #region Test Method 2
            //List<TaxiInfo> taxiInfos = new List<TaxiInfo>();
            //foreach (TaxiInfo taxiInfo in MainForm.TaxiList.Values)
            //{
            //    //if (Common.CommonRoutine.GetShortDistance(longitude, latitude, taxiInfo.Longitude, taxiInfo.Latitude) <= distance)
            //    //{
            //    //    taxiInfos.Add(taxiInfo);
            //    //}
            //    if (Math.Abs(taxiInfo.Latitude - latitude) < distance && Math.Abs(taxiInfo.Longitude - longitude) < distance)
            //    {
            //        taxiInfos.Add(taxiInfo);
            //    }
            //}
            #endregion
        }

        public List<TaxiInfo> GetNearbyGpsByCompany(
            double longitude, double latitude, double distance,string company)
        {
            double d = distance * 2 / 100.0f;
            double d2 = d;

            lock (AcceptMainForm.TaxiList.SyncRoot)
            {

                List<TaxiInfo> fasterInfos = new List<TaxiInfo>();

                fasterInfos.AddRange(AcceptMainForm.TaxiList.Values.Cast<TaxiInfo>().
                    Where(faster => Math.Abs(faster.Latitude - latitude) < d
                        && Math.Abs(faster.Longitude - longitude) < d2
                        && faster.CompanyName==company
                         ));
             
                return fasterInfos;
            }
          
        }
        
        #region User Role
        public bool CheckUser(string userName, string password)
        {
            bool bCheckUser = _bUser.CheckUser(userName, password);
            Console.WriteLine(DateTime.Now.ToString() + "bCheckUser--" + bCheckUser.ToString());
            return bCheckUser;
        }

        public UserInfo CheckUserWithReturn(string userName, string password)
        {
            return _bUser.CheckUserWithReturn(userName, password);
        }
         
        public bool ChangePassWordByUserName(string userName, string newPwd)
        {
            return _bUser.ChangePassWordByUserName(userName, newPwd);
        }

        public bool UserAdd(UserInfo model)
        {
            return _bUser.Add(model);
        }

        public bool UserUpdate(UserInfo model)
        {
            return _bUser.Update(model);
        }

        public bool UserDelete(int id)
        {
            return _bUser.Delete(id);
        }

        public bool UserDeleteList(string idlist)
        {
            return _bUser.DeleteList(idlist);
        }

        public DataSet UserGetList(string strWhere)
        {
            return _bUser.GetList(strWhere);
        }

        public bool UserExist(string userName)
        {
            return _bUser.Exists(userName);
        }

        public bool RoleAdd(RoleInfo model)
        {
            return _bRole.Add(model);
        }

        public bool RoleUpdate(int id, string name, string permission, string remark)
        {
            return _bRole.Update(id, name, permission, remark);
        }

        public string[] GetRoleInfoByUserName(string username)
        {
            return _bRole.GetRoleInfoByUserName(username);
        }

        public bool RoleDelete(int id)
        {
            return _bRole.Delete(id);
        }

        public bool RoleDeleteList(string idlist)
        {
            return _bRole.DeleteList(idlist);
        }

        public DataSet RoleGetList(string strWhere)
        {
            return _bRole.GetList(strWhere);
        }

        public bool RoleExist(string roleName)
        {
            return _bRole.Exists(roleName);
        }
        #endregion

        #region GmapOverlay
        public bool GmapoverlayAdd(Model.GmapoverlayInfo model)
        {
            return _bGmapoverlay.Add(model);
        }

        public bool GmapoverlayUpdate(Model.GmapoverlayInfo model)
        {
            return _bGmapoverlay.Update(model);
        }

        public bool GmapoverlayDelete(int id)
        {
            return _bGmapoverlay.Delete(id);
        }

        public Model.GmapoverlayInfo GmapoverlayGetModel(int id)
        {
            return _bGmapoverlay.GetModel(id);
        }

        public DataSet GmapoverlayGetList(string strWhere)
        {
            return _bGmapoverlay.GetList(strWhere);
        }

        public DataSet GmapoverlayGetListByParameter(string parameter, string parameterVaule)
        {
            return _bGmapoverlay.GetList(parameter, parameterVaule);
        }

        public int GmapoverlayGetRecordCount(string strWhere)
        {
            return _bGmapoverlay.GetRecordCount(strWhere);
        }
        #endregion

        #region PhoneUser

        public bool PhoneUserExists(string phoneNumber)
        {
            return _bPhoneUser.Exists(phoneNumber);
        }

        public bool PhoneUserAdd(Model.PhoneUserInfo model)
        {
            return _bPhoneUser.Add(model);
        }

       
        public bool PhoneUserDelete(int id)
        {
            return _bPhoneUser.Delete(id);
        }

        public Model.PhoneUserInfo PhoneUserGetModel(int id)
        {
            return _bPhoneUser.GetModel(id);
        }

        public DataSet PhoneUserGetList(string strWhere)
        {
            return _bPhoneUser.GetList(strWhere);
        }

        #endregion

        #region Driver
        public bool DriverExistsCardId(string cardId)
        {
            return _bDriver.ExistsCardId(cardId);
        }

        public bool DriverAdd(DriverInfo model)
        {
            return _bDriver.Add(model);
        }

        public bool DriverUpdate(DriverInfo model)
        {
            return _bDriver.Update(model);
        }

        public bool DriverUpdateState(string phoneNumber, int state)
        {
            return _bDriver.UpdateState(phoneNumber, state);
        }

        public bool DriverChangePassword(string cardId, string oldPwd, string newPwd)
        {
            return _bDriver.ChangePassword(cardId, oldPwd, newPwd);
        }

        public bool DriverDelete(int id)
        {
            return _bDriver.Delete(id);
        }

        public DriverInfo DriverGetModelByPhoneNum(string phoneNumber)
        {
            return _bDriver.GetModelByPhoneNum(phoneNumber);
        }

        public DataSet DriverGetList(string strWhere)
        {
            return _bDriver.GetList(strWhere);
        }

        #endregion

        #region Taxi
       
        public bool TaxiExistsPhoneNum(string phoneNumber)
        {
            return _bTaxi.ExistsPhoneNum(phoneNumber);
        }

        public bool TaxiAdd(TaxiInfo model)
        {
            return _bTaxi.Add(model);
        }

        public bool TaxiUpdate(TaxiInfo model)
        {
            return _bTaxi.Update(model);
        }

        public bool TaxiUpdateState(string phoneNumber, int state)
        {
            return _bTaxi.UpdateState(phoneNumber, state);
        }

        public bool TaxiDelete(int id)
        {
            return _bTaxi.Delete(id);
        }

        public DataSet TaxiGetList(string strWhere)
        {
            return _bTaxi.GetList(strWhere);
        }
        #endregion

        #region GpsHistory
        public void AddTaxiGpsHistoryInfo(TaxiGpsHistoryInfo taxiGpsHistoryInfo)
        {
            _bTaxiGpsHistory.Add(taxiGpsHistoryInfo);
        }

        public DataSet TaxiGpsHistoryGetList(string driverPhoneNumber, DateTime startTime, DateTime endTime)
        {
            return _bTaxiGpsHistory.GetList(driverPhoneNumber, startTime, endTime);
        }
        public DataSet TaxiGpsHistoryGetListWhere(string strWhere)
        {
            return _bTaxiGpsHistory.GetList(strWhere);
        }

        public int TaxiGpsHistoryGetRecordCount(string strWhere)
        {
            return _bTaxiGpsHistory.GetRecordCount(strWhere);
        }

        public DataSet TaxiGpsHistoryGetStatisticsList(string strWhere)
        {
            return _bTaxiGpsHistory.GetStatisticsList(strWhere);
        }

        public DataSet GetTaxiOnlineCountReport(string strWhere)
        {
            return _bTaxiGpsHistory.GetTaxiOnlineCountReport(strWhere);
        }

        public DataSet TaxiGpsHistoryGetStatisResult(int intObject, string strValue,
           int dateType, string strWhere)
        {
            return _bTaxiGpsHistory.GetStatisResult(intObject, strValue, dateType, strWhere);
        }
        #endregion

        #region Order

        public DataSet OrderGetList(string strWhere)
        {
            return _bOrder.GetList(strWhere);
        }

        #endregion

        public DataSet CompanyGetList(string strWhere)
        {
            return _bCompany.GetList(strWhere);
        }


    }
}
